this week assignment is to write an application that interfaces a user with an input &/or output device that we made. But since my board is in the lab I used the Arduino and bread board to complete this assignment.
From the first time I decided the idea of my final project, I waited this week specially, because the idea depends on controlling the LEDs using a GUI mainly. To do that I learned how to use tkinter library in python.
Since this is a very new topic for me, the first step is to download the python software from this website by choosing the version that compatible with your operating system, I downloaded the 3.7 version. then run the downloaded file as an administrator to start the installation, during this step you have to make some choices, use the images below as a guide.
As you can see in the images above, when I installed python, I decided to install IDLE with it, which is the Integrated Development Learning Environment that provided from python, so I didn’t need any external IDE, but Using IDLE is not a requirement for using Python. There are many other IDEs that can be used to write Python program like Pycharm which I downloaded and tried to use but I liked the IDLE more.
The second step is learning the python programming language, to do that I read much tutorials about it, like learning path in real python website and fab academy tutorials . and after this stage I started feeling confident to proceed with the assignment.
'as a beginner I decided to make a simple GUI to control LED with Arduino just to be on or off or blinking, to do that I divided my work to 3 phases, the hardware, Arduino code and python code.
the first phase is the hardware, so I connected the LED to the Arduino using the breadboard and jumbling wires, and 220-ohm resistors as I did in the input devices week. You can see the schematic below.
The second phase is Arduino code, I used serial. Available function which Gets the number of bytes (characters) available for reading from the serial port. And used if conditions to control the status of the LED depending on the value from the serial port, you can see the code below.
const int ledPin = 13; int incomingByte; void setup() { // initialize serial communication: Serial.begin(9600); // initialize the LED pin as an output: pinMode(9, OUTPUT); pinMode(10, OUTPUT); pinMode(11, OUTPUT); } void loop() { // see if there's incoming serial data: if (Serial.available() > 0) { // read the oldest byte in the serial buffer: incomingByte = Serial.read(); if (incomingByte == '1') { analogWrite(9,255 ); analogWrite(10,0 ); analogWrite(11,52 ); } if (incomingByte == '2') { digitalWrite(9,0 ); digitalWrite(10,0 ); digitalWrite(11,0 ); } else { analogWrite(9,255 ); analogWrite(10,0 ); analogWrite(11,52 ); delay(500); digitalWrite(9,0 ); digitalWrite(10,0 ); digitalWrite(11,0 ); delay(500); analogWrite(9,255 ); analogWrite(10,0 ); analogWrite(11,52 ); } }
In order to create a GUI with python, I had to install pyserial library which provides support for serial connections. to do that I opened the command prompt in windows and wrote pip install pyserial it will start installing pyserial library and I closed the terminal.
In the IDLE window, I started writing the code the first thing to do is importing the pyserial library and the tkinter library which is the standard GUI library for Python. Then I started creating functions for the buttons, to assign for each function the value that will return to the Arduino program. And called each function of them in the button command. you can see the code below.
import serial import tkinter Arduino_Data = serial.Serial('com3',9600) def led_color1(): Arduino_Data.write(b'1') def led_color2(): Arduino_Data.write(b'0') def blink(): Arduino_Data.write(b'2') control_window = tkinter.Tk() Button = tkinter.Button btn1=Button(control_window,text='color1',command=led_color1) btn2=Button(control_window,text='color2',command=led_color2) btn3=Button(control_window,text='blink',command=blink) btn1.grid(row=1,column=1) btn2.grid(row=1,column=2) btn3.grid(row=1,column=3) control_window.mainloop()
After that, all what I had to do is uploading the Arduino code to the Arduino circuit, and then in the IDLE window clicked RUN to start the application, a new window contains the buttons appears and I could control the LED from them.
Then I started upgrading my work by adding more controlling options and more buttons to application.below my second Arduino code, which I wrote to make the RGB LED give me different colors depending on the value that will return from the python code. And of course I edited the python code to have buttons equals the number of colors options.
char serialData; //check always the pins int redPin= 9; int greenPin = 11; int bluePin = 10; void setup() { pinMode(redPin, OUTPUT); pinMode(greenPin, OUTPUT); pinMode(bluePin, OUTPUT); Serial.begin(9600); } void loop() { int valoareIluminare = analogRead(0); Serial.println(valoareIluminare, DEC); delay(100); if (Serial.available() > 0) { serialData = Serial.read(); Serial.print(serialData); if(serialData == '0') { analogWrite(redPin, 255); //red analogWrite(greenPin, 0); analogWrite(bluePin, 0); } else if (serialData == '1') {//green analogWrite(redPin, 0); analogWrite(greenPin, 0); analogWrite(bluePin, 255); } else if (serialData == '2') {//blue analogWrite(redPin, 0); analogWrite(greenPin, 255); analogWrite(bluePin, 0); } else if (serialData == '3') {//white analogWrite(redPin, 255); analogWrite(greenPin, 255); analogWrite(bluePin, 255); } else if (serialData == '4') {//yellow analogWrite(redPin, 255); analogWrite(greenPin, 0); analogWrite(bluePin, 255); } else if (serialData == '5'){//silver analogWrite(redPin, 0); analogWrite(greenPin, 192); analogWrite(bluePin, 0); } } }
import serial import tkinter import tkinter.messagebox arduinoData = serial.Serial('com3',9600) def led_red(): arduinoData.write(b'0') def led_green(): arduinoData.write(b'1') def led_blue(): arduinoData.write(b'2') def led_white(): arduinoData.write(b'3') def led_yellow(): arduinoData.write(b'4') def led_silver(): arduinoData.write(b'5') # MAIN ledrgb = tkinter.Tk() ledrgb.title("Arduino RGB Led Control") ledrgb.configure(background="grey") #exit function def close_window(): arduinoData.write(b'0') ledrgb.destroy() exit() Button = tkinter.Button # buttons btn1 = Button(ledrgb, text="red", command = led_red, height=5,width=5) btn2 = Button(ledrgb, text="green", command = led_green ,height=5,width=5) btn3 = Button(ledrgb, text="blue", command = led_blue, height=5,width=5) btn4 = Button(ledrgb, text="white", command = led_white ,height=5,width=5) btn5 = Button(ledrgb, text="yellow", command = led_yellow ,height=5,width=5) btn6 = Button(ledrgb, text="silver", command=led_silver ,height=5,width=5) btn7 = Button(ledrgb, text="Exit", command=close_window) .grid(row=3) btn1.grid(row=0,column=1) btn2.grid(row=0,column=2) btn3.grid(row=1,column=1) btn4.grid(row=1,column=2) btn5.grid(row=2,column=1) btn6.grid(row=2,column=2) ledrgb.mainloop()
and here is the video of upgraded RGB LEDs control
Now since we are in the lab now, I repeated the same steps I did for the RGB LED , but this time with my board ( attiny44 with RGBLED).
Of course I had to make some changes for the code. since I’m now using Attiny 44 which do not support the Serial communication ( it does not have serial pins) , I had to use the software serial commands which enables you to use any digital pin as serial pin.
I first included its library, and then defined the pins that I want to use them as serial pins, (which are from the schematic PA0 & PA1). When we initialize the software serial pins we have to give it name (it should not be a revered word), I named it serial (the ‘s ‘ is not capital as in the Serial command). We will use this name everywhere we want to use the software serial in the code.
Then I set the speed for the communication to be 115200 (baud rate), and then completed the code with the conditions I wanted to light the RGB LED.
Before trying to test the code with the python, I tried to test it with the serial monitor, just to test that the code is doing what I wanted it to do .
For the python code I didn’t change a lot if things, I just edited the baud rate for the communication, and of course the port number. And since I changed the lightings in the Arduino code, I added buttons for the new conditions.
Below you can see both Arduino and python codes and the video.
#include SoftwareSerial.h SoftwareSerial serial(PA0,PA1); char incomingByte; void setup() { serial.begin(115200); pinMode(7, OUTPUT); pinMode(6, OUTPUT); pinMode(8, OUTPUT); } void loop() { if (serial.available()) { incomingByte = serial.read(); switch (incomingByte) { case '1': serial.println (incomingByte); serial.println ("GREEN"); digitalWrite(7,HIGH ); digitalWrite(6,LOW ); digitalWrite(8,HIGH ); break; case '2': serial.println (incomingByte); serial.println ("BLUE"); digitalWrite(7,HIGH ); digitalWrite(6,HIGH ); digitalWrite(8,LOW ); break; case '3': serial.println (incomingByte); serial.println ("RED"); digitalWrite(7, LOW ); digitalWrite(6, HIGH); digitalWrite(8, HIGH); break; case '4': serial.println (incomingByte); serial.println ("RANDOM"); analogWrite(7, random(0,255)); analogWrite(6, random(0,255)); analogWrite(8, random(0,255)); break; } } }
import serial import tkinter Arduino_Data = serial.Serial('com5',115200) def green(): Arduino_Data.write(b'1') def blue(): Arduino_Data.write(b'2') def red(): Arduino_Data.write(b'3') def random(): Arduino_Data.write(b'4') control_window = tkinter.Tk() Button = tkinter.Button btn1=Button(control_window,text='green',command=green) btn2=Button(control_window,text='blue',command=blue) btn3=Button(control_window,text='red',command=red) btn4=Button(control_window,text='random',command=random) btn1.grid(row=1,column=1) btn2.grid(row=1,column=2) btn3.grid(row=2,column=1) btn4.grid(row=2,column=2) import serial import tkinter Arduino_Data = serial.Serial('com5',115200) def green(): Arduino_Data.write(b'1') def blue(): Arduino_Data.write(b'2') def red(): Arduino_Data.write(b'3') def random(): Arduino_Data.write(b'4') control_window = tkinter.Tk() Button = tkinter.Button btn1=Button(control_window,text='green',command=green) btn2=Button(control_window,text='blue',command=blue) btn3=Button(control_window,text='red',command=red) btn4=Button(control_window,text='random',command=random) btn1.grid(row=1,column=1) btn2.grid(row=1,column=2) btn3.grid(row=2,column=1) btn4.grid(row=2,column=2) import serial import tkinter Arduino_Data = serial.Serial('com5',115200) def green(): Arduino_Data.write(b'1') def blue(): Arduino_Data.write(b'2') def red(): Arduino_Data.write(b'3') def random(): Arduino_Data.write(b'4') control_window = tkinter.Tk() Button = tkinter.Button btn1=Button(control_window,text='green',command=green) btn2=Button(control_window,text='blue',command=blue) btn3=Button(control_window,text='red',command=red) btn4=Button(control_window,text='random',command=random) btn1.grid(row=1,column=1) btn2.grid(row=1,column=2) btn3.grid(row=2,column=1) btn4.grid(row=2,column=2)
Since my final project idea depends on creating a display matrix, I decided to make a simple matrix and control it with python. I applied the 3 phases exactly as before, starting with the connecting process I attached 11 LEDs together in one line and connected each with a 220-ohm resistor, see image below.
For the Arduino code, I added 3 conditions each one will turn the LEDs in a certain pattern, and added buttons of these patterns in the python code of course.
char serialData; //check always the pins int led1= 2; int led2 = 3; int led3 = 4; int led4= 5; int led5 = 6; int led6 = 7; int led7= 8; int led8 = 9; int led9 = 10; int led10 = 11; int led11 = 12; void setup() { pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(led3, OUTPUT); pinMode(led4, OUTPUT); pinMode(led5, OUTPUT); pinMode(led6, OUTPUT); pinMode(led7, OUTPUT); pinMode(led8, OUTPUT); pinMode(led9, OUTPUT); pinMode(led10, OUTPUT); pinMode(led11, OUTPUT); Serial.begin(9600); } void loop() { int valoareIluminare = analogRead(0); Serial.println(valoareIluminare, DEC); delay(100); if (Serial.available() > 0) { serialData = Serial.read(); Serial.print(serialData); if(serialData == '0') { //all on digitalWrite(led1, HIGH); digitalWrite(led2, HIGH); digitalWrite(led3, HIGH); digitalWrite(led4, HIGH); digitalWrite(led5, HIGH); digitalWrite(led6, HIGH); digitalWrite(led7, HIGH); digitalWrite(led8, HIGH); digitalWrite(led9, HIGH); digitalWrite(led10, HIGH); digitalWrite(led11, HIGH); delay (500); digitalWrite(led1, LOW); digitalWrite(led2, LOW); digitalWrite(led3, LOW); digitalWrite(led4, LOW); digitalWrite(led5, LOW); digitalWrite(led6, LOW); digitalWrite(led7, LOW); digitalWrite(led8, LOW); digitalWrite(led9, LOW); digitalWrite(led10, LOW); digitalWrite(led11, LOW); delay (500); digitalWrite(led1, HIGH); digitalWrite(led2, HIGH); digitalWrite(led3, HIGH); digitalWrite(led4, HIGH); digitalWrite(led5, HIGH); digitalWrite(led6, HIGH); digitalWrite(led7, HIGH); digitalWrite(led8, HIGH); digitalWrite(led9, HIGH); digitalWrite(led10, HIGH); digitalWrite(led11, HIGH); delay (500); digitalWrite(led1, LOW); digitalWrite(led2, LOW); digitalWrite(led3, LOW); digitalWrite(led4, LOW); digitalWrite(led5, LOW); digitalWrite(led6, LOW); digitalWrite(led7, LOW); digitalWrite(led8, LOW); digitalWrite(led9, LOW); digitalWrite(led10, LOW); digitalWrite(led11, LOW); delay (500); } else if (serialData == '1') {//series on/off digitalWrite(led1, HIGH); delay(300); digitalWrite(led2, HIGH); delay(300); digitalWrite(led3, HIGH); delay(300); digitalWrite(led4, HIGH); delay(300); digitalWrite(led5, HIGH); delay(300); digitalWrite(led6, HIGH); delay(300); digitalWrite(led7, HIGH); delay(300); digitalWrite(led8, HIGH); delay(300); digitalWrite(led9, HIGH); delay(300); digitalWrite(led10, HIGH); delay(300); digitalWrite(led11, HIGH); delay(300); digitalWrite(led1, LOW); delay(300); digitalWrite(led2, LOW); delay(300); digitalWrite(led3, LOW); delay(300); digitalWrite(led4, LOW); delay(300); digitalWrite(led5, LOW); delay(300); digitalWrite(led6, LOW); delay(300); digitalWrite(led7, LOW); delay(300); digitalWrite(led8, LOW); delay(300); digitalWrite(led9, LOW); delay(300); digitalWrite(led10, LOW); delay(300); digitalWrite(led11, LOW); delay(300); digitalWrite(led1, HIGH); delay(300); digitalWrite(led2, HIGH); delay(300); digitalWrite(led3, HIGH); delay(300); digitalWrite(led4, HIGH); delay(300); digitalWrite(led5, HIGH); delay(300); digitalWrite(led6, HIGH); delay(300); digitalWrite(led7, HIGH); delay(300); digitalWrite(led8, HIGH); delay(300); digitalWrite(led9, HIGH); delay(300); digitalWrite(led10, HIGH); delay(300); digitalWrite(led11, HIGH); delay(300); digitalWrite(led1, LOW); delay(300); digitalWrite(led2, LOW); delay(300); digitalWrite(led3, LOW); delay(300); digitalWrite(led4, LOW); delay(300); digitalWrite(led5, LOW); delay(300); digitalWrite(led6, LOW); delay(300); digitalWrite(led7, LOW); delay(300); digitalWrite(led8, LOW); delay(300); digitalWrite(led9, LOW); delay(300); digitalWrite(led10, LOW); delay(300); digitalWrite(led11, LOW); delay(300); } } else if (serialData == '2') {//dancing digitalWrite(led1, HIGH); digitalWrite(led11, HIGH); delay(500); digitalWrite(led2, HIGH); digitalWrite(led10, HIGH); delay(500); digitalWrite(led3, HIGH); digitalWrite(led9, HIGH); delay(500); digitalWrite(led4, HIGH); digitalWrite(led8, HIGH); delay(500); digitalWrite(led5, HIGH); digitalWrite(led7, HIGH); delay(500); digitalWrite(led6, HIGH); delay(500); digitalWrite(led1, LOW); digitalWrite(led11, LOW); delay(500); digitalWrite(led2, LOW); digitalWrite(led10, LOW); delay(500); digitalWrite(led3, LOW); digitalWrite(led9, LOW); delay(500); digitalWrite(led4, LOW); digitalWrite(led8, LOW); delay(500); digitalWrite(led5, LOW); digitalWrite(led7, LOW); delay(500); digitalWrite(led6, LOW); delay(500); digitalWrite(led1, HIGH); digitalWrite(led11, HIGH); delay(500); digitalWrite(led2, HIGH); digitalWrite(led10, HIGH); delay(500); digitalWrite(led3, HIGH); digitalWrite(led9, HIGH); delay(500); digitalWrite(led4, HIGH); digitalWrite(led8, HIGH); delay(500); digitalWrite(led5, HIGH); digitalWrite(led7, HIGH); delay(500); digitalWrite(led6, HIGH); delay (500); digitalWrite(led1, LOW); digitalWrite(led11, LOW); delay(500); digitalWrite(led2, LOW); digitalWrite(led10, LOW); delay(500); digitalWrite(led3, LOW); digitalWrite(led9, LOW); delay(500); digitalWrite(led4, LOW); digitalWrite(led8, LOW); delay(500); digitalWrite(led5, LOW); digitalWrite(led7, LOW); delay(500); digitalWrite(led6, LOW); delay(500); } /*else if (serialData == '3') {//white analogWrite(redPin, 255); analogWrite(greenPin, 255); analogWrite(bluePin, 255); } else if (serialData == '4') {//yellow analogWrite(redPin, 255); analogWrite(greenPin, 0); analogWrite(bluePin, 255); } else if (serialData == '5'){// analogWrite(redPin, 0); analogWrite(greenPin, 192); analogWrite(bluePin, 0); }*/ }
import serial import tkinter import tkinter.messagebox arduinoData = serial.Serial('com3',9600) def all_led(): arduinoData.write(b'0') def series_led(): arduinoData.write(b'1') def dancing_led(): arduinoData.write(b'2') # MAIN ledrgb = tkinter.Tk() ledrgb.title("Arduino RGB Led Control") ledrgb.configure(background="grey") #exit function def close_window(): arduinoData.write(b'0') ledrgb.destroy() exit() Button = tkinter.Button # buttons btn1 = Button(ledrgb, text="all", command = all_led, height=5,width=5) btn2 = Button(ledrgb, text="series", command = series_led ,height=5,width=5) btn3 = Button(ledrgb, text="dancing", command = dancing_led, height=5,width=5) btn4 = Button(ledrgb, text="Exit", command=close_window ,height=5,width=5) btn1.grid(row=0,column=1) btn2.grid(row=0,column=2) btn3.grid(row=1,column=1) btn4.grid(row=1,column=2) ledrgb.mainloop()
and below video shows the LEDs lighting in different patterns depending on the button pressed.
I designed a mobile application to control my final project via Bluetooth, you can see all the detailes in the Final Project Tracking page.